﻿using BenchmarkDotNet.Attributes;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SkiaSharp;

namespace Benchmark;

[SimpleJob]
[MemoryDiagnoser]
internal class ImageBenchmark
{
    private const string _prefix = "thumb_";
    private readonly string[] _files = ["img/img1.jpg", "img/img2.jpg", "img/img3.jpg"];
    private string GetThumbnailFileName(string fileName, string prefix) => Path.Combine(Path.GetDirectoryName(fileName)!, _prefix + prefix + Path.GetFileName(fileName));

    [Benchmark]
    public void RunImageSharp()
    {
        foreach (var file in _files)
        {
            UseImageSharp(file);
        }
    }
    [Benchmark]
    public void RunSkiaSharp()
    {
        foreach (var file in _files)
        {
            UseSkiaSharp(file);
        }
    }
    [Benchmark]
    public void RunNetVips()
    {
        foreach (var file in _files)
        {
            UseNetVips(file);
        }
    }

    private void UseImageSharp(string fileName)
    {
        using var image = SixLabors.ImageSharp.Image.Load<Rgba32>(fileName);
        image.Mutate(x => x.Resize(new Size(128, 0)));
        image.Save(GetThumbnailFileName(fileName, "ImageSharp_"));
    }
    private void UseSkiaSharp(string fileName)
    {
        using var stream = File.OpenRead(fileName);
        using var skData = SKData.Create(stream);
        using var codec = SKCodec.Create(skData);

        // boost performance by first getting an approximate size so we can decode the image directly in this dimension
        var supportedScale = codec.GetScaledDimensions((float)128 / codec.Info.Width);
        var newImageInfo = new SKImageInfo(supportedScale.Width, supportedScale.Height);
        using var destinationImage = SKBitmap.Decode(codec, newImageInfo);
        using var resizedImage = destinationImage.Resize(newImageInfo, new SKSamplingOptions(SKFilterMode.Nearest, SKMipmapMode.Nearest));
        using var outputImage = SKImage.FromBitmap(resizedImage);
        using var data = outputImage.Encode();
        using var outputStream = File.Open(GetThumbnailFileName(fileName, "SkiaSharp_"), FileMode.Create);
        data.SaveTo(outputStream);
        outputStream.Close();
        stream.Close();
    }
    private void UseNetVips(string fileName)
    {
        using var image = NetVips.Image.NewFromFile(fileName);
        using var resizedImage = image.ThumbnailImage(128, 0);
        resizedImage.WriteToFile(GetThumbnailFileName(fileName, "NetVips_"));
    }
}